Executing it
-
$item = $phad->item('item/name', ['key'=>'value']);: load a phad item -
$item->html(): return a string of the finished item - EXPERIMENTAL, pass
':data'=>'NAME'in arguments to specify the name of ap-datanode to use. Declare attributename="NAME"on the<p-data>node to match. This usage may change in future versions. - DEPRECATED, pass
'data.name'=>'NAME'to do the same a:data
Just, other stuff
-
$phad->exit_on_redirect = falseto stop redirects fromexiting
Basics / Item Nodes / Some forms tuff
- Ex:
<div item="Blog"> - Ex:
<h1 prop="title">inside the blog item div - Variables available:
object $Blog,array $BlogRow,stdClass $BlogInfo... there's more ... see your compiled output -
<h1 prop="title" filter="html_escape">to applyhtml_escapefilter before dispalying title. (see filter documentation) - add
loop="inner"to loop INSIDE the div (so the div only displays once, but it's content shows for each row) - pass
['Blog'=>$Blog]or['BlogList'=>[$Blog1, $Blog2]]to use that as data (skips access checks, since it uses the default data node) -
<x-item item="Blog">... works like any other item node, exceptx-itemwill hide itself -
<x-prop prop="body"></x-prop>to display$Blog->bodywithout showing an html node - override certain methods on Phad to further customize things ....
- delete
Filtercontroller. I'm not using it ... but it might be in some tests? ... phad just directly handles filters now
Phad Overrides
Of course, you can override any part of Phad ...
-
function object_from_row(array $row, $ItemInfo): object(default returns(object)$ItemRow)- Custom object can add properties with
<p prop="some_prop">without the prop being in the db
- Custom object can add properties with
-
function onSubmit($ItemInfo, &$ItemRow): bool, returnfalseto stop submission -
function onDidSubmit($ItemInfo, $ItemRow), called after a successful submission to do extra work -
function onWillDelete($ItemInfo): bool, returnfalseto stop deletion
Phad Handlers
Set $phad->handlers['handler_name'] = function(...$args){} ... then $phad->handler_name() will call that function.
The function name can be anything, just need any callable.
- 'can_read_row' (optional):
function can_read_row(array $ItemRow,object $ItemInfo,string $ItemName): bool... returns true by default - 'item_initialized' (required?):
function item_initialized(stdClass $ItemInfo): void - 'user_has_role' (required?):
function user_has_role(string $roles): boolwhere$rolesshould be likeguest|admin|moderator(though that's up to you & how you define your role access in attribute handlers)
Routes
-
<route pattern="/some/route/"></route> -
<route pattern="/some/{slug}/></route>"for dynamic routes. Requires a data node like<p-data where="Blog.slug LIKE :slug"></p-data> - You can have multiple
<route>nodes in a single file & each can have a<sitemap>node
Sitemaps
- Goes inside a
<route>node. Can use dynamic patterns - For
<route pattern="/some/{slug}/":<sitemap sql="SELECT slug FROM blog">... - The
<sitemapnode can declare attributes and/or the sql can selectpriority,lastmod, andchangefreq - @todo
<sitemap handler="handler_name"points to$phad->sitemap->handlers['handler_name']and ... idk ... feature not implemented yet - @todo allow individual route sitemapping like For
<route pattern="/some/route/":<sitemap></sitemap>... hack this by settingsql="SELECT 1 as oneon the sitemap node ...
Property filters
- Ex:
<p prop="description" filter="my_filter">yields<p><?=$phad->filter($Blog->description)?></p> -
commonmark:markdownToHtmluses"league/commonmark": "^1.0"... for now ... which you have to add to your composer.json bc the dependency is inrequire-devfor this package - add other filters with
$phad->filters['filter_name'] = function($property_value){}
<on> nodes
- if one
<p-data>node is granted, then only the successful's200status will be displayed - if no
<p-data>nodes are granted, then each data node's<on>node will display ... showing 403, 404, 500, etc ... depending what the error was for that node - what about
<on>nodes not nested in<p-data>? I'm not sure.
<p-data> nodes
- must be direct child of an item node
-
sqlattribute to craft a full query. (you can use multiple lines inside the double quotes) -
where,limit,orderby, andcolsattributes to refine if not usingsqlattribute. do not include the sql verb inside the double quotes -
accessattribute used to limit access. See the docs on attribute call handlers -
ifattribute may contain php code such asisset($some_var). This code will beeval'd & if it returns false, then this data node will not be used. -
data_loader="some_key"can be used to load data by defining$phad->data_loaders["some_key"] = function(DomNode, ItemInfo).
Hook Nodes
all hook nodes can contain php code, html, whatever. For a better understanding of these, use them & look at the compiled output. the submit nodes are all for forms only.
-
<onsubmit>php code: Set$ItemInfo->mode = nullto stop submission or modify$ItemRowto change what gets submitted -
<didsubmit>php code -
<failsubmit> php code -
<diddelete> php code: for code to run only AFTER the database row is deleted -
<willdelete> php code: For code to run BEFORE the database row is deleted -
<on s=404|403|500|200> php code... as direct child of<p-data>or direct child of<div item="Blog">
Attribute Call Handlers
cansubmit, candelete, and diddelete all go on <form item="Blog"> nodes.
These take strings like role:moderator;call:handler_name. Access handlers should return true/false. Hook handlers (diddelete) do not need to return anything.
For handler_name, do $phad->access_handlers['handler_name'] = function(...$args){}
-
cansubmit:function(stdClass $ItemInfo, array $RowToStore): bool -
candelete:function(stdClass $ItemInfo): bool -
diddelete:function(stdClass $ItemInfo): void -
<button access="call:can_do_buttons">:function(array $node_info): bool(forcan_read_node()) ...$node_infois the html node's attributes +tagName -
<p-data access="call:is_data_allowed">:function(array $data_node_info, stdClass $ItemInfo): boolwhere$data_node_infois the html node's attributes +tagName
Forms
- add
target="/blogs/{slug}/"to form node to automatically redirect after submission. the slug will be filled in by the submitted row - See hook nodes & attribute call handlers
- To delete a field request
/page/?phad_action=delete&id=ID_TO_DELETE - To enable deletion, add
candeleteattribute to form. If empty, there will be no checks & deletion will always succeed.candelete="false"declines deletion.candelete='role:admin'orcandelete="call:your_func"for checks (see Attribute Call handlers) -
<errors></errors>node as direct child of the form will automatically display errors in a div withclass="errors"and each message is in a<p>with no class. - in your attribute call handlers, do
$Info->submit_errors[] = ['msg'=>"Some Message"];to display in the<errors>node - set
$Info->cancel_submit = trueto prevent a submission. - manually displaying errors ...
<?php foreach($ItemInfo->submit_errors as $m){echo $m['msg'];}- Or you can use the items feature:
<div item="ItemSubmitErrors"><p prop="msg"></p></div>... this method may be removed. idk. it isn't tested
- Or you can use the items feature:
- file uploads: Kinda meh, see below
-
backendinputs:<input type="backend" name="slug">... You might use<onsubmit>to convert a title into a slug. To store the slug in the db, add$BlogRow['slug'] = $the_slug& thebackendinput so it passes validation. backend inputs are removed from the html. - @TODO
<input type="hidden" name="id">is added automatically - For inputs added via php (thus not in the html when compiled by phad), add to the onsubmit
$ItemInfo->properties['prop'] => ['type'=>'text','tagName'=>'input']. You may change the type or add other attributes that exist for form inputs (such asminlength/maxlength, orrequired). thetagName=>'input'part is necessary for validation. - For submitted fields that you DON'T want in the database, do
unset($ItemRow['field'])& in some casesunset($ItemInfo->properties['field'])in your<onsubmit>code